package com.aiyige.page.globalsearch;


import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.BaseFragment;
import com.aiyige.base.api.ApiManager;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.model.Page;
import com.aiyige.model.User;
import com.aiyige.model.moment.entity.Moment;
import com.aiyige.model.sns.Follow;
import com.aiyige.page.globalsearch.adapter.SearchAdapter;
import com.aiyige.page.globalsearch.event.EventGlobalSearch;
import com.aiyige.page.globalsearch.event.EventJumpGlobalSearchTab;
import com.aiyige.page.globalsearch.model.SearchData;
import com.aiyige.page.globalsearch.util.SearchPageInterface;
import com.aiyige.page.globalsearch.util.SearchUtil;
import com.aiyige.page.home.HomeFollowPage;
import com.aiyige.page.home.adapter.RecommendFollowAdapter;
import com.aiyige.page.home.model.FollowItem;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.ErrorUtil;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.RetrofitUtil;
import com.aiyige.utils.SafeAsyncTask;
import com.aiyige.utils.StringUtils;
import com.aiyige.utils.UIHelper;
import com.aiyige.utils.widget.AutoRefreshCommonDataView;
import com.aiyige.utils.widget.CommonDataView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.fastjson.JSON;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.netease.nim.uikit.common.util.string.StringUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;

/**
 * A simple {@link Fragment} subclass.
 */
public class SearchAllPage extends BaseFragment implements SearchPageInterface, CommonDataView.RetrofitStub, AutoRefreshCommonDataView.Callback {
    String searchWord = "";
    View header;
    View countHeader;
    TextView countTv;
    @BindView(R.id.cdv)
    AutoRefreshCommonDataView cdv;
    Unbinder unbinder;
    SearchAdapter searchAdapter;
    RecommendFollowAdapter recommendFollowAdapter;
    RecyclerView relatedUserRv;
    View viewAllRelatedUserBtn;
    volatile boolean shouldRefresh = false;


    public SearchAllPage() {
        setAutoRegisterEventBus(true);
    }

    public static BaseFragment newInstance() {
        return new SearchAllPage();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.page_search_all, container, false);
        unbinder = ButterKnife.bind(this, view);
        searchAdapter = new SearchAdapter(getActivity());
        recommendFollowAdapter = new RecommendFollowAdapter();
        cdv.config(searchAdapter, this);
        cdv.setCallback(this);
        searchAdapter.setHeaderAndEmpty(true);
        initHeader(inflater);
        return view;
    }

    public void initHeader(LayoutInflater inflater) {
        searchAdapter.addHeaderView(LayoutInflater.from(getContext()).inflate(R.layout.recycler_view_header_safe_line, (ViewGroup) cdv.getRecyclerView().getParent(), false));
        header = inflater.inflate(R.layout.global_search_all_header, (ViewGroup) cdv.getRecyclerView().getParent(), false);
        header.setVisibility(View.GONE);
        viewAllRelatedUserBtn = header.findViewById(R.id.viewAllRelatedUserBtn);
        viewAllRelatedUserBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(EventJumpGlobalSearchTab.newBuilder()
                        .index(1)
                        .build());
            }
        });
        relatedUserRv = header.findViewById(R.id.relatedUserRv);
        relatedUserRv.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                int position = relatedUserRv.getChildAdapterPosition(view);
                if (position == 0) {
                    outRect.set(UIHelper.dip2px(8), 0, 0, 0);
                } else if (position == relatedUserRv.getAdapter().getItemCount() - 1) {
                    outRect.set(0, 0, UIHelper.dip2px(8), 0);
                } else {
                    outRect.set(0, 0, 0, 0);
                }
            }
        });
        searchAdapter.addHeaderView(header);

        countHeader = inflater.inflate(R.layout.global_search_count_header, (ViewGroup) cdv.getRecyclerView().getParent(), false);
        countHeader.setVisibility(View.GONE);
        countTv = countHeader.findViewById(R.id.countTv);
        searchAdapter.addHeaderView(countHeader);
        relatedUserRv.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
        recommendFollowAdapter.bindToRecyclerView(relatedUserRv);
        recommendFollowAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                if (AccountUtil.isLogin()) {
                    FollowItem followItem = recommendFollowAdapter.getItem(position);
                    if (!followItem.isFollowed()) {
                        new AddFollowTask(getActivity(), position).execute();
                    } else {
                        new DeleteFollowTask(getActivity(), position).execute();
                    }
                } else {
                    ARouter.getInstance()
                            .build(ARouterConfig.LoginPage)
                            .navigation();
                }
            }
        });
        recommendFollowAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                switch (view.getId()) {
                    case R.id.avatarIv: {
                        FollowItem followItem = recommendFollowAdapter.getItem(position);
                        ARouter.getInstance()
                                .build(ARouterConfig.UserPage)
                                .withString("userId", followItem.getId())
                                .navigation();
                        break;
                    }
                }
            }
        });

    }


    @Override
    protected void initData() {
        shouldRefresh = true;
        cdv.doRefreshRequest();
        searchUser();
    }

    public void searchUser() {
        new SearchUserTask(getActivity()).execute();
    }

    @Override
    public String pageTitle() {
        return StringUtils.getString(R.string.all);
    }

    @Override
    public int pageType() {
        return SearchUtil.PAGE_TYPE_SEARCH_ALL;
    }

    @Override
    public void searchWord(String searchWord) {
        this.searchWord = searchWord;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }

    @Override
    public Call<ResponseBody> call(long currentPage) {
        shouldRefresh = false;
        return ApiManager.getService().allSearchZone(searchWord, "", currentPage, 20);
    }

    @Override
    public CommonDataView.HandleResult handleResponse(String respJson, List resultList) {
        try {
            Page page = JSON.parseObject(respJson, Page.class);
            List<Moment> momentList = new LinkedList<>();
            if (!TextUtils.isEmpty(page.getContent())) {
                momentList.addAll(JSON.parseArray(page.getContent(), Moment.class));
            }
            for (Moment moment : momentList) {
                resultList.add(SearchData.parse(new Moment(moment), searchWord));
            }
            countTv.setText(StringUtils.getString(R.string.total_result_count, StringUtils.formatNum(page.getTotalElements())));
            return new CommonDataView.HandleResult(page.isLast());
        } catch (Exception e) {
            return new CommonDataView.HandleResult(e.getMessage());
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(EventGlobalSearch event) {
        switch (event.getType()) {
            case EventGlobalSearch.TYPE_DO_SEARCH: {
                if (isFragmentVisible()) {
                    shouldRefresh = true;
                    cdv.refresh();
                    searchUser();
                } else {
                    cdv.showRefreshing();
                    setForceLoad(true);
                }
                break;
            }
        }


    }

    @Override
    public void onClearRequestState() {
        if (shouldRefresh) {
            cdv.refresh();
        }
        if (ListUtil.isEmpty(searchAdapter.getData())) {
            countHeader.setVisibility(View.GONE);
        } else {
            countHeader.setVisibility(View.VISIBLE);
        }
    }

    public class SearchUserTask extends SafeAsyncTask<Object, Object, Object> {
        List<FollowItem> followItemList = new LinkedList<>();

        public SearchUserTask(Activity activity) {
            super(activity);
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (ListUtil.isEmpty(followItemList)) {
                header.setVisibility(View.GONE);
            } else {
                header.setVisibility(View.VISIBLE);
                recommendFollowAdapter.setNewData(followItemList);
                relatedUserRv.scrollToPosition(0);
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService().searchUser(searchWord, 0, 12).execute();
                if (response.code() != ResponseCode.OK) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                String json = RetrofitUtil.getResponseBodyAsString(response);
                Page page = JSON.parseObject(json, Page.class);
                List<User> tempList = new LinkedList<>();
                if (!TextUtils.isEmpty(page.getContent())) {
                    tempList.addAll(JSON.parseArray(page.getContent(), User.class));
                }
                for (User item : tempList) {
                    User user = new User(item);
                    followItemList.add(FollowItem.newBuilder()
                            .avatar(user.getAvatar())
                            .id(user.getId())
                            .name(user.getAccount())
                            .followed(!TextUtils.isEmpty(user.getMineBackup().getUserFollowId()))
                            .followId(user.getMineBackup().getUserFollowId())
                            .build());
                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }
    }


    public class AddFollowTask extends SafeAsyncTask<Object, Object, Object> {
        int position;
        FollowItem source;
        Follow result;

        public AddFollowTask(Activity activity, int position) {
            super(activity, R.string.loading);
            this.position = position;
            source = recommendFollowAdapter.getItem(position);
        }

        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {

            } else {
                try {
                    if (recommendFollowAdapter.getItem(position).getId().equals(source.getId())) {
                        FollowItem followItem = recommendFollowAdapter.getItem(position);
                        followItem.setFollowId(result.getId());
                        followItem.setFollowed(true);
                        recommendFollowAdapter.setData(position, source);
                    }
                } catch (Exception e) {

                }
            }
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService().addFollow(Follow.newBuilder()
                        .beFollowedId(source.getId())
                        .followerId(AccountUtil.getCurrentUser().getId())
                        .build())
                        .execute();
                if (response.code() != ResponseCode.CREATED) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                String json = RetrofitUtil.getResponseBodyAsString(response);
                Follow follow = JSON.parseObject(json, Follow.class);
                if (follow == null) {
                    throw new Exception("添加关注失败");
                }
                result = new Follow(follow);
                return null;
            } catch (Exception e) {
                return e;
            }
        }
    }


    public class DeleteFollowTask extends SafeAsyncTask<Object, Object, Object> {
        int position;
        FollowItem source;

        public DeleteFollowTask(Activity activity, int position) {
            super(activity, R.string.loading);
            this.position = position;
            source = recommendFollowAdapter.getItem(position);
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService()
                        .deleteFollow(source.getFollowId())
                        .execute();
                if (response.code() != ResponseCode.NO_CONTENT) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }


        @Override
        public void safeOnPostExecute(Object o) {
            if (o instanceof Exception) {
            } else {
                try {
                    if (recommendFollowAdapter.getItem(position).getId().equals(source.getId())) {
                        FollowItem followItem = recommendFollowAdapter.getItem(position);
                        followItem.setFollowId("");
                        followItem.setFollowed(false);
                        recommendFollowAdapter.setData(position, followItem);
                    }
                } catch (Exception e) {

                }
            }
        }
    }


}
